-- c#IList的实现，基于table，保证table的有序数组没有hole的出现。下标是按lua规范从1开始的。

-- 模块定义
local M = 
{
    _base_class = require "objects.Object",
    _class_name = "collections.List"
};
setmetatable (M, {__index = _G;});
_ENV = M;

-- 引用模块
local Tools = require "tools.CommonTools"

-- 方法定义

operation_table = Tools.CreateOperationTable (_base_class)

-- 返回list中的元素个数
function operation_table.Count (self)
    return #self;
end;

-- 获取指定索引处的元素
function operation_table.GetItemAt (self, index)
    if (index < 1 or index > #self) then
        error ("Argument is out of range")
    end;
    return self[index];
end;

-- 设置指定索引处的元素
function operation_table.SetItemAt (self, index, value)
    if (index < 1 or index > #self) then
        error ("Argument is out of range.");
    end;        

    self[index] = value;
end;

-- 将某项添加到list中
function operation_table.Add (self, value)
    self[#self + 1] = value;
end;

-- 多list中移除所有项
function operation_table.Clear (self)
    while #self > 0 do
        table.remove (self);
    end
end;

-- 确定list中是否包含特定值
function operation_table.Contains (self, value)
    for index = 1, #self do
        if self[index] == value then
            return true;
        end;
    end;
    return false;
end;

-- 确定list中特定项的索引
function operation_table.IndexOf (self, value)
    for index = 1, #self do
        if self[index] == value then
            return index;
        end;
    end;
    return 0;
end;

-- 将特定值插入指定索引处
function operation_table.Insert (self, index, value)
    if (index < 1 or index > #self + 1) then
        error ("Argument is out of range");
    end;
    table.insert (self, index, value);
end;

-- 从list中移除和指定值匹配的第一项
function operation_table.Rmv (self, value)
    local index = self:IndexOf (value);
    if index ~= 0 then
        table.remove (self, index);
    end;
end;

-- 从list中移除指定索引处的值
function operation_table.RmvAt (self, index)
    if index < 1 or index > #self then
        error ("Argument is out of range");
    end; 

    table.remove (self, index);
end;

-- 格式化
function operation_table.__tostring (self)
    local list_str = "";
    for index = 1, self:count() do
        list_str = list_str .. tostring(self:get_item_at (index)) .. ", ";
    end;
    return "[" .. list_str .. "]";
end;

-- 构造函数
function NewList ()
    -- 将instance本身作为底层容器
    instance = _base_class.NewObject ();
    Tools.PrepareInstance (M, instance);

    return instance;
end;

return M;
